<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Parameter Converters</title>
</head>

<body>

<h2>Parameter Converters</h2>

<h3>Automatic conversion of textual values to Java objects</h3>

<p>JBehave automatically converts the textual representation of a
parameter extracted from the step with the parameter type of the matched
method in the steps instance class. Let's go back to our example to make
this point clear: the textual step</p>
<pre class="brush: bdd">
    Given a stock of symbol STK1 and a threshold of 10.0
</pre>
<p>would map to the Java method</p>
<pre class="brush: java">
    @Given("a stock of symbol $symbol and a threshold of $threshold")
    public void aStock(String symbol, double threshold) {
        // ...
    }
</pre>
<p>where the two arguments which are identified as parameters in
matching the textual step to the annotation pattern are: "STK1" and
"1.0". These are converted respectively to a <b>String</b> and a <b>double</b>.</p>
<p>If we had comma-separated values, e.g</p>
<pre class="brush: bdd">
    Given a stock of symbols STK1,STK2 and thresholds of 10.0,20.0
</pre>
<p>these would handled automatically as well, provided the type of
the parameter was a <a
    href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/List.html">List</a></p>
<script type="syntaxhighlighter" class="brush: java">
<![CDATA[
    @Given("a stock of symbols $symbols and thresholds $thresholds")
    public void aStock(List<String> symbols, List<Double> thresholds) {
        // ...
    }
]]>
</script>
<p>Another common use case is that of date conversion. The step
would typically look like:</p>
<pre class="brush: bdd">
    When a stock of symbol STK1 is traded on 09/09/2009
</pre>
<p>and the matching step is</p>
<pre class="brush: java">
    @When("a stock of symbol $symbol is traded on $tradedOn")
    public void aStockIsTradedOn(String symbol, Date tradedOn) {
        // ...
    }
</pre>

<h3>Built-in parameter converters</h3>

<p>JBehave provides out-of-the-box support for several types.</p>
<p>At the core of the parameter conversion mechanism lies the <a
    href="javadoc/core/org/jbehave/core/steps/ParameterConverters.html">ParameterConverters</a>
facade. The built-in support for Java types is provided by
implementations of this interface. Specifically:</p>
<ul>
    <li><a
        href="javadoc/core/org/jbehave/core/steps/ParameterConverters.NumberConverter.html">NumberConverter</a></li>
    <li><a
        href="javadoc/core/org/jbehave/core/steps/ParameterConverters.NumberListConverter.html">NumberListConverter</a></li>
    <li><a
        href="javadoc/core/org/jbehave/core/steps/ParameterConverters.StringListConverter.html">StringListConverter</a></li>
    <li><a
        href="javadoc/core/org/jbehave/core/steps/ParameterConverters.DateConverter.html">DateConverter</a></li>
    <li><a
        href="javadoc/core/org/jbehave/core/steps/ParameterConverters.EnumConverter.html">EnumConverter</a></li>
    <li><a
        href="javadoc/core/org/jbehave/core/steps/ParameterConverters.EnumListConverter.html">EnumListConverter</a></li>
    <li><a
        href="javadoc/core/org/jbehave/core/steps/ParameterConverters.ExamplesTableConverter.html">ExamplesTableConverter</a></li>
    <li><a
        href="javadoc/core/org/jbehave/core/steps/ParameterConverters.MethodReturningConverter.html">MethodReturningConverter</a></li>
</ul>

<h3>Customising parameter converters</h3>

<p>To customise built-in parameter converters, simply re-add the
instances with the customised configuration, as the newly added
instances will take precedence over the default ones:</p>
<script type="syntaxhighlighter" class="brush: java">
<![CDATA[
    @Override
    public Configuration configuration() {
        Keywords keywords = new LocalizedKeywords(locale());
        Configuration configuration = new MostUsefulConfiguration()
                .useParameterConverters(
                        new ParameterConverters().addConverters(customConverters(keywords)));
        return configuration;
    }
    
    private ParameterConverter[] customConverters(Keywords keywords) {
        List<ParameterConverter> converters = new ArrayList<ParameterConverter>();
        converters.add(new NumberConverter(NumberFormat.getInstance(locale()))); // custom number format
        converters.add(new DateConverter(new SimpleDateFormat("yyyy-MM-dd")));  // custom date pattern
        converters.add(new ExamplesTableConverter(new ExamplesTableFactory(new LoadFromClasspath(this.getClass()))); // custom examples table loader
        return converters.toArray(new ParameterConverter[converters.size()]);
    }

]]>
</script>

<h3>Defining parameter converters</h3>

<p>Users can define their own custom parameter converters by
implementing the <a
    href="javadoc/core/org/jbehave/core/steps/ParameterConverters.ParameterConverter.html">ParameterConverter</a>
interface.</p>
<p>Let's consider the use case where we have persistable objects
accessible via persister interface from a String identifier. Then a
custom parameter converter may come in very handy so that the lookup of
the persistable object is done behind the scenes and does not get in the
way of the step implementation. E.g. given the converter:</p>
<script type="syntaxhighlighter" class="brush: java">
<![CDATA[
    public class TraderConverter implements ParameterConverter {
        private TraderPersister traderPersister = ... // inject persister in converter

        public boolean accept(Type type) {
            if (type instanceof Class<?>) {
                return Trader.class.isAssignableFrom((Class<?>) type);
            }
            return false;
        }

        public Object convertValue(String value, Type type) {
            return traderPersister.retrieveTrader(value);
        }
    }
]]>
</script>
<p>the step</p>
<pre class="brush: bdd">
    Given a trader of name Mauro
</pre>
<p>would map to the method:</p>
<pre class="brush: java">
    @Given("a trader of name $name")
    public void aTrader(Trader trader) {
        // Trader object is provided to the method as parameter
    }
</pre>

<h3>Annotated methods as parameter converters</h3>

<p>In some cases defining the converter in Configuration is not an
option as the conversion is much more dynamical in nature. In this case,
one can annotated Steps method to act as parameter converters when
annotated by <a
    href="javadoc/core/org/jbehave/core/annotations/AsParameterConverter.html">@AsParameterConverter</a>:
</p>

<pre class="brush: java">
    public MySteps() {
        // Method used as dynamical parameter converter
        @AsParameterConverter
        public Trader createTrader(String name){
            return traderPersister.retrieveTrader(name);
        }
    
    }
</pre>
<p>The parameter converter configuration is done in the <a
    href="javadoc/core/org/jbehave/core/steps/AbstractStepsFactory.html">AbstractStepsFactory</a>
so you can use any implementation of <a
    href="javadoc/core/org/jbehave/core/steps/InjectableStepsFactory.html">InjectableStepsFactory</a>
that extends the abstract implementation, e.g.:</p>
<pre class="brush: java">
    public MyStory extends JUnitStory {
        @Override
        public InjectableStepsFactory stepsFactory() {
            return new InstanceStepsFactory(configuration(), new MySteps(), new BeforeAfterSteps());
        }
    }
</pre>

<div class="clear">
<hr />
</div>

</body>
</html>